package com.atguigu.hbase.demos;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * Created by Smexy on 2022/5/16
 *
 *      ①创建和HBase的连接
 *              连接自动维护了连接hbase和zookeeper的功能。
 *              连接可以通过ConnectionFactory实例化，谁创建，谁调用close负责关掉
 *               操作hbase都需要通过这个对象进行，从这个对象中获取Table,Admin对象
 *               连接的创建是重量级和线程安全，可以在一个App中只创建一次连接，在不同的线程中共享(设置为成员变量或静态变量)。
 *               Table,Admin对象是轻量级(创建不费劲，不耗资源)，不是线程安全，一般是每个程序的方法中都各自创建各自的。
 *
 *
 *               HBaseConfiguration.create() 创建一个Configuration对象
 *                      和 new Configuration()的区别在于，上者会 多读 hbase-site.xml 和hbase-default.xml
 *
 *      ②获取一张表
 *                  如果想DML(CRUD)操作一张表，需要对这张表声明一个Table对象
 *
 *                  DDL(建库建表)操作一张表，需要一个Admin对象
 *
 *      ③对表进行增删改查
 *              Table.put(Put a): put
 *              Table.get(Get a): get
 *              Table.delete(Delete a): delete
 *              Table.scan(Scanner a): scan
 *
 *
 *      ④工具类
 *              Bytes.toXxxx() :  byte [] 转指定的xxx类型
 *              Bytes.toBytes(Xxx类型)：  把xxx类型转byte []
 *
 *              CellUtil.cloneXxx(Cell c) : 拷贝Cell中的某个属性，例如rowkey，列族等
 */
public class HBaseUtil {

    private Connection connection;

    /*
            遍历Get的一行结果

            一行由若干列组成，每个列都有若干个cell
     */
    public  void parseResult(Result result){

        //获取一行中最原始的cell
        Cell[] cells = result.rawCells();

        //遍历
        for (Cell cell : cells) {

            System.out.println("rowkey："+Bytes.toString(CellUtil.cloneRow(cell)));
            System.out.println("列名"+Bytes.toString(CellUtil.cloneFamily(cell))+ ":"+Bytes.toString(CellUtil.cloneQualifier(cell)));
            System.out.println("值:"+Bytes.toString(CellUtil.cloneValue(cell)));

        }

    }

    {

        try {
            connection = ConnectionFactory.createConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /*
            定义一个返回Put对象的方法
            Put对象封装了要操作的Cell

            Put  表名，rowkey，列族名，列名，value
     */

    public Put createPut(String rowkey,String cf,String cq,String value){

        Put put = new Put(Bytes.toBytes(rowkey));

        // java语法糖   A.() return A
       return put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(cq), Bytes.toBytes(value));
    }

    public Table getTable(String tableName) throws IOException {

        // isBlank 判断一个字符串是否是  null,"","回车,空格白字符"
        if (StringUtils.isBlank(tableName)){

            throw new RuntimeException("表名非法!");

        }

        Table table = connection.getTable(TableName.valueOf(tableName));

        return table;

    }

    public void closeConn() throws IOException {

        if (connection != null){

            connection.close();

        }

    }


}
